<?php

namespace App\Models;


use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class DiningReserve extends Base
{
    //分页获取列表数据
    public function getPageList($options=[],$where=[],$whereDates){
        try{
            $limit = (isset($options['limit']) && $options['limit']) ? $options['limit'] : 1;
            $page = (isset($options['page']) && $options['page']) ? $options['page'] : 1;
            $model = DB::table('dining_reserves')
                ->leftJoin('dinings','dinings.id','=','dining_reserves.tid')
                ->leftJoin('users','dining_reserves.uid','=','users.id');
            if(!empty($whereDates)){
                $model = $model->whereDate('sitday','>=',$whereDates[0])->whereDate('sitday','<',$whereDates[1]);
            }
            $model=$model->select('dining_reserves.*','dinings.title','dinings.title_zn','users.contact','users.username','users.username_zn')
                    ->where($where)->orderBy('dining_reserves.created_at','desc');
            $result = $this->paging($model,$page,$limit);
            return $result;
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }
    }

    //添加订单
    public function oneInsert($data=array(),$lang="zn"){
        try {
            $uid = $data['uid'];
            $user = (new User())->where('id',$uid)->select('total','balance','cycle_balance','deleted_at')->first();
            if(!$user){
                return [
                    'code'=>1,
                    'message'=>'用户不存在'
                ];
            }
            if($user->deleted_at){
                return [
                    'code'=>1,
                    'message'=>'用户已禁用,不可操作'
                ];
            }
            $hasorder = $this->where([['timetype','=',$data['timetype']],['sitday','=',$data['sitday']],['tid','=',$data['tid']]])->whereIn('status',[1,2,3])->first();
            if($hasorder){
                return [
                    'code'=>1,
                    'message'=>'该桌目前已被预订,您可选择其他桌子、时间日期或时间段'
                ];
            }
            $data['ordersn'] = date("YmdHis").mt_rand(100,999);
            $data['status'] = 2;
            $data['total'] = 0;
            $data['earnest'] = 0;
            $data['ordtype'] = 2;
            $data['created_at'] = date('Y-m-d H:i:s');
            $data['updated_at'] = date('Y-m-d H:i:s');
            $did = $this->insertGetId($data); //添加预定订单
            if($did){
                return [
                    'code'=>0,
                    'data'=>$did
                ];
            }else{
                return [
                    'code'=>1,
                    'message'=>'添加失败'
                ];
            }
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }
    }

    //更新订单
    public function doUpdate($data=array()){
        try {
            $hasorder = $this->where([
                            ['timetype','=',$data['timetype']],['sitday','=',$data['sitday']],['tid','=',$data['tid']],['id','<>',$data['id']]
                        ])->whereIn('status',[1,2,3])->first();
            if($hasorder){
                return [
                    'code'=>1,
                    'message'=>'该桌目前已被预订,您可选择其他桌子、时间日期或时间段'
                ];
            }
            $data['updated_at'] = date('Y-m-d H:i:s');
            $res = $this->where('id',$data['id'])->update($data);
            if($res){
                return [
                    'code'=>0,
                    'data'=>$data['id']
                ];
            }else{
                return [
                    'code'=>1,
                    'message'=>'更新失败'
                ];
            }
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }
    }

    //改变订单状态
    public function changeStatus($data=array()){
        try{
            $order = self::find($data['id']);
            $cando = true;
            $where = [];
            $update = [];
            switch($data['status']) {
                //后台接单操作,将所有待审核的商品变成待付款(2)
                case 2:
                    $cando =  $order->status === 1?true:false;
                    $where[] = ['status','=',1];
                    $update = ['status'=>2];
                    break;
                //后台到场操作,商品状态无需改变
                case 3:
                    $cando =  $order->status === 2?true:false;
                    $where[] = ['status','=',2];
                    $update = ['status'=>2];
                    break;
                //后台退订,改变所有待付款的商品为退订
                case 5:
                    $cando =  ($order->status === 1 || $order->status === 2 || $order->status === 3)?true:false;
                    $where[] = ['status','=',2];
                    $update = ['status'=>4];
                    break;
                //取消订单,
                case 6:
                    $cando = ($order->status === 1 || $order->status === 0)?true:false;
                    $where[] = ['status','=',1];
                    $update = ['status'=>6];
            }
            if(!$cando){
                return [
                    'code'=>1,
                    'message'=>'该操作有误'
                ];
            }
            $promodel = new DiningReserveProd();
            $order->status = $data['status'];
            $update['updated_at'] = date('Y-m-d H:i:s');
            DB::transaction(function ()use($promodel,$order,$where,$update){
                $order->save();
                $promodel->where($where)->update($update);
            },5);
            return [
                'code'=>0,
                'data'=>$data['id']
            ];
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }

    }

    //发起结账
    public function orderCheckOut($id){
        try {
            $order = self::find($id);
            $user = (new User())->select('id','balance','cycle_balance')->find($order->uid);
            $orderProds = (new DiningReserveProd())->where('did',$id)->where('status',2)->get();
            $yinTotal = 0; //交易总金额
            foreach ($orderProds as $prod){
                if($prod->status==3){
                    $prodprice = $prod->proprice * $prod->pronum;
                    $yinTotal += $prodprice;
                }
            }
            $yinTotal -= $order->earnest;
            //形成交易订单
            $ranstr = Str::random(4);
            $transNo = $ranstr.date("YmdHis");
            $transInsert = [
                'number'=>$yinTotal,
                'transtype'=>2,
                'paytype'=>1,
                'uid'=>$order->uid,
                'status'=>1,
                'orderid'=>$id,
                'transno'=>$transNo,
                'transname'=>'餐桌预定订单结账'
            ];
            $transition['balance'] = $user->balance;
            $transition['cycle_balance'] = $user->cycle_balance;
            $transid = (new Transition())->insertGetId($transInsert);
            if($transid){
                $transInsert['id'] = $transid;
                return [
                    'code'=>0,
                    'data'=>$transInsert
                ];
            }else{
                return [
                    'code'=>1,
                    'message'=>'发起结账失败，请重试'
                ];
            }
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }
    }

    //确定结账
    public function orderSettle($data){
        DB::beginTransaction();
        try {
            $trans = (new Transition())->where('transno',$data['transno'])->first();
            if(!$trans){
                return [
                    'code'=>1,
                    'message'=>'交易单不存在'
                ];
            }
            $order = $this->where('id',$trans->orderid)->first();
            if(!$order){
                return [
                    'code'=>1,
                    'message'=>'订单不存在'
                ];
            }
            $order->status = 4;
            $trans->status = 2;
            $now = date('Y-m-d H:i:s');
            $user = User::find($trans->uid);
            $total =  $user->total;
            if(!$user){
                return [
                    'code'=>1,
                    'message'=>'用户不存在'
                ];
            }
            $trans->paytype = $data['paytype'];
            $number = $data['number'] - $data['youhui'];
            $trans->number = $number;
            $order->youhui = $data['youhui'];
            if($data['paytype']==1){ //钱包支付
                if($user->balance - $number<0){
                    return [
                        'code'=>1,
                        'message'=>'钱包余额不足'
                    ];
                }
                $trans->balance = $user->balance - $number;
                $user->balance = $trans->balance;
                $trans->cycle_balance = $user->cycle_balance;
                $user->total += $number;
            }elseif($data['paytype']==2){ //反馈钱包支付
                if($user->cycle_balance - $data['number']<0){
                    return [
                        'code'=>1,
                        'message'=>'反馈钱包余额不足'
                    ];
                }
                $trans->cycle_balance = $user->cycle_balance - $data['number'];
                $user->cycle_balance = $trans->cycle_balance;
                $trans->balance = $user->balance;
            }else{ //现金支付
                $trans->cycle_balance = $user->cycle_balance;
                $trans->balance = $user->balance;
                $user->total += $number;
            }
            if($data['paytype']==1||$data['paytype']==3){
                $levinfo = (new UserLevel())->where([
                    ['min','<=',$total],['max','>',$total]
                ])->select('id','cycle_rate','integral')->first()->toArray();
                if(empty($levinfo)){
                    $levinfo = [
                        'id'=>0,
                        'cycle_rate'=>0,
                        'integral'=>0
                    ];
                }
                //形成反馈交易单
                $cycle = intval($number * $levinfo['cycle_rate'] / 10000);
                if($cycle>0){
                    $randstr = Str::random(4);
                    $cycle_transNo = date('YmdHis').$randstr;
                    $cycleTrans = new self();
                    $cycleTrans->number = $cycle;
                    $cycleTrans->transtype = 6;
                    $cycleTrans->paytype = 0;
                    $cycleTrans->transname = '消费反馈';
                    $cycleTrans->transno = $cycle_transNo;
                    $cycleTrans->balance = $user->balance;
                    $cycleTrans->cycle_balance = $user->cycle_balance + $cycle;
                    $cycleTrans->uid = $user->id;
                    $cycleTrans->orderid = 0;
                    $cycleTrans->status = 2;
                    $cycleTrans->save();
                    $user->cycle_balance += $cycle;//加上反馈金额
                }
                //计算积分反馈数
                $integral = intval($number / 100 * $levinfo['integral'] / 10000);
                //形成反馈积分记录
                if($integral>0){
                    $randstr = Str::random(4);
                    $integral_transNo = date('YmdHis').$randstr;
                    $integralTrans = new JifenDetail();
                    $integralTrans->number = $cycle;
                    $integralTrans->transtype = 2;
                    $integralTrans->transname = '消费积分反馈';
                    $integralTrans->transno = $integral_transNo;
                    $integralTrans->coin = $user->coin + $integral;
                    $integralTrans->uid = $user->id;
                    $integralTrans->orderid = 0;
                    $integralTrans->status = 2;
                    $integralTrans->save();
                    $user->coin += $integral;//加上反馈积分
                }
                //查找推广人
                $spreadid = (new SpreadRecord())->where('uid',$user->id)->value('spreadid');
                //推荐人首单返佣金
                if($spreadid){
                    $backid = (new RakeBack())->where([
                        ['spreadid','=',$spreadid],['uid','=',$user->id],['status','=',1]
                    ])->value('id');
                    if(!$backid && in_array($data['transtype'],[1,3])){ //判断有无佣金反馈记录且是消费
                        $spreduser = (new User())->where('spreadid',$spreadid)->first();
                        if($spreduser && !$spreduser->deleted_at){
                            $spredRate = (new UserLevel())->where([ ['min','<=',$spreduser->total],['max','>',$spreduser->total] ])->value('spred_rate');
                            if($spredRate>0){
                                $spredback = intval($number * $spredRate / 10000);
                                $orderTotal = $order->total;
                                //形成返佣记录
                                $backid =(new RakeBack())->insertGetId([
                                    'spreadid'=>$spreadid,
                                    'ordertype'=>1,
                                    'uid'=>$user->id,
                                    'orderid'=>$trans->orderid,
                                    'total'=>$orderTotal,
                                    'number'=>$spredback,
                                    'status'=>1,
                                    'created_at'=>$now,
                                    'updated_at'=>$now
                                ]);
                                //形成返佣交易单
                                $backTrans = new self();
                                $randstr = Str::random(4);
                                $back_transNo = date('YmdHis').$randstr;
                                $backTrans->number = $spredback;
                                $backTrans->paytype = 0;
                                $backTrans->transtype = 8;
                                $backTrans->transname = '推广返佣';
                                $backTrans->transno = $back_transNo;
                                $backTrans->balance = $spreduser->balance + $spredback;
                                $backTrans->cycle_balance = $spreduser->cycle_balance;
                                $backTrans->uid = $spreduser->id;
                                $backTrans->orderid = $backid;
                                $backTrans->status = 2;
                                $backTrans->save();
                                $spreduser->balance += $spredback;//加上返佣金额
                                $spreduser->save();
                            }
                        }
                    }
                }
            }
            $trans->save();
            $user->save();
            $order->save();
            (new DiningReserveProd())->where('did',$order->id)->update(['status'=>3,'updated_at'=>date('Y-m-d H:i:s')]);
            DB::commit();
            return [
                'code'=>0,
                'data'=>[
                    'transno'=>$data['transno'],
                    'number'=>$number
                ]
            ];
        }catch (\Exception $e){
            DB::rollBack();
            return [
                'code'=>1,
                'message'=>$e->getMessage()
            ];
        }
    }

    //餐桌预下单
    public function insertReserve($data,$token,$lang='zn'){
        try {
            $user = (new User())->where('token',$token)->first();
            if($user->deleted_at){
                return [
                    'code'=>1,
                    'message'=>$this->lang['USER_FORBIDDEN'][$lang]
                ];
            }
            $this->total = $data['total'];
            $this->earnest = $data['earnest'];
            $this->ordersn = date('YmdHis').mt_rand(1000,9999);
            $this->uid = $user->id;
            $this->tid = $data['tid'];
            $this->sitday = $data['sitday'];
            $this->ordtype = $data['ordtype'];
            $this->pernum = $data['pernum'];
            $this->timetype = $data['timetype'];
            $this->remark = $data['remark'];
            $newtoken = $this->setToken($user->id);
            if($data['ordtype']==1){ //预定点单
                $this->status = 0;
                $that = $this;
                if(!isset($data['prods'])){
                    return [
                        'code'=>1,
                        'message'=>$this->lang['EMPTY_PRODS'][$lang]
                    ];
                }
                $insertProdData =json_decode($data['prods'],true);
                DB::transaction(function ()use ($user,&$that,$newtoken,$insertProdData){
                    $that->save();
                    foreach($insertProdData as &$inset){
                        $inset['did'] = $that->id;
                        $inset['created_at'] = date('Y-m-d H:i:s');
                        $inset['updated_at'] = date('Y-m-d H:i:s');
                    }
                    (new DiningReserveProd())->insert($insertProdData); //添加订单商品数据
                    $user->token = $newtoken;
                    $user->save();
                },5);
            }else{ //现场点单
                $this->status = 1;
                $that = $this;
                DB::transaction(function ()use ($user,&$that,$newtoken){
                    $that->save();
                    $user->token = $newtoken;
                    $user->save();
                },5);
            }
            return  [
                'code'=>0,
                'data'=>[
                    'id'=>$that->id,
                    'token'=>$newtoken
                ]
            ];
        }catch (\Exception $e){
            return [
                'code'=>1,
                'message'=>$this->lang['ERROR'][$lang]
            ];
        }
    }
}
